﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Net;
using Newtonsoft.Json;
using System.Linq;
using ServerIntegration.JsonTranslationClasses.NWoDVampire;
using ServerIntegration.JsonTranslationClasses.QueryClasses;

namespace ServerIntegration
{
    /// <summary>
    /// Much of this was built with thanks to
    /// http://json2csharp.com/
    /// </summary>
    public class SiteQuery
    {
        public const string NormalLoginSite = "http://strange-aeons.herokuapp.com/login";
        private String _loginSite;

        private WebClientEx client = new WebClientEx();
        private readonly string _username;
        private readonly string _password;
        private readonly string _characterQueryUrl;
        private const string LoginSiteCharactersToRemove = "login";
        private const string CharacterQueryURLExtension = "get?Type=Character&id=";
        private string BaseURL;
        public bool LoginSuccessful { get; set; }
        //private string CharacterQueryURLExtension = "http://strange-aeons.herokuapp.com/get?Type=Character&name"=;


        public SiteQuery(string loginSite, string username, string password)
        {
            _username = username;
            _loginSite = loginSite;
            _password = password;
            BaseURL = loginSite.Replace(LoginSiteCharactersToRemove, "");
            _characterQueryUrl = loginSite.Replace(LoginSiteCharactersToRemove, CharacterQueryURLExtension);
        }

        public List<RootObject> QueryAllCharacters()
        {
            var ids = GameIDsForUser();
            var characters = CharactersForGames(ids.ToList());
            return characters.ToList();
        }

        public IEnumerable<RootObject> CharactersForGames(List<int> gameIDsList)
        {
            var characterSiteQuery = BaseURL + "get?Type=Game&id=";
            foreach (var cur in gameIDsList)
            {
                var gameQuery = characterSiteQuery + cur;
                var info = client.DownloadString(gameQuery);
                var json = ParseJsonForGameQuery(info);
                if (json.success != null)
                {
                    foreach (var curCharacter in json.success.body.characters)
                    {
                        yield return QueryCharacter(curCharacter.id);
                    }
                }
            }
        }

        public IEnumerable<int> GameIDsForUser()
        {
            var userQueryString = BaseURL + "get?Type=User&name=" + _username;
            var info = client.DownloadString(userQueryString);
            var json = ParseJsonForUserQuery(info);
            if (json.success != null)
            {
                foreach (var cur in json.success)
                {
                    foreach (var curGame in cur.games)
                    {
                        yield return curGame.id;
                    }
                }
            }
        }

        private UserQuery.RootObject ParseJsonForUserQuery(string info)
        {
            var json = JsonConvert.DeserializeObject
                <UserQuery.RootObject>(info);
            //if (json.Success == null)
            //    return null;
            return json;
        }


        private GameQuery.RootObject ParseJsonForGameQuery(string info)
        {
            var json = JsonConvert.DeserializeObject
                <GameQuery.RootObject>(info);
            //if (json.Success == null)
            //    return null;
            return json;
        }

        public void Login()
        {
            var values = new NameValueCollection
            {
                {"email", _username},
                {"password", _password},
            };
            try
            {
                // Authenticate
                var info = client.UploadValues(_loginSite, values);
                LoginSuccessful = true;
            }
            catch (WebException)
            {
                LoginSuccessful = false;
            }
        }

        private RootObject QueryCharacter(int targetCharacterID)
        {
            // Download desired page
            string characterSiteQuery = _characterQueryUrl + targetCharacterID;
            var info = client.DownloadString(characterSiteQuery);
            return ParseJsonForVampire(info);
        }

        private RootObject ParseJsonForVampire(string info)
        {
            var json = JsonConvert.DeserializeObject<RootObject>(info);
            if (json.success == null)
                return null;
            return json;
        }
    }
}